package services

import (
	"encoding/json"
	"fmt"
	"log"
	"strconv"
	"strings"

	"internal-net-bridge-server/internal/config"
	"internal-net-bridge-server/internal/models"
)

// ConfigService 配置服务
type ConfigService struct{}

// NewConfigService 创建配置服务实例
func NewConfigService() *ConfigService {
	return &ConfigService{}
}

// GetConfig 获取指定key的配置
func (cs *ConfigService) GetConfig(key string) (string, error) {
	var cfg models.Config
	err := config.DB.Where("config_key = ?", key).First(&cfg).Error
	if err != nil {
		return "", fmt.Errorf("获取配置失败 [%s]: %v", key, err)
	}
	return cfg.ConfigValue, nil
}

// SetConfig 设置配置
func (cs *ConfigService) SetConfig(key, value, desc string) error {
	var cfg models.Config
	err := config.DB.Where("config_key = ?", key).First(&cfg).Error
	if err != nil {
		// 创建新配置
		cfg = models.Config{
			ConfigKey:   key,
			ConfigValue: value,
			Desc:        desc,
		}
		return config.DB.Create(&cfg).Error
	} else {
		// 更新现有配置
		cfg.ConfigValue = value
		if desc != "" {
			cfg.Desc = desc
		}
		return config.DB.Save(&cfg).Error
	}
}

// GetAppConfig 获取完整应用配置
func (cs *ConfigService) GetAppConfig() (*models.AppConfig, error) {
	appConfig := &models.AppConfig{}

	// DNS配置
	dnsEnabled, _ := cs.GetConfigBool("dns.enabled", false)
	dnsProviders, _ := cs.GetConfig("dns.providers")
	dnsDefaultProvider, _ := cs.GetConfig("dns.default_provider")
	dnsDomain, _ := cs.GetConfig("dns.domain")
	dnsPublicIP, _ := cs.GetConfig("dns.public_ip")

	appConfig.DNS = models.DNSConfig{
		Enabled:         dnsEnabled,
		Providers:       dnsProviders,
		DefaultProvider: dnsDefaultProvider,
		Domain:          dnsDomain,
		PublicIP:        dnsPublicIP,
	}

	// 隧道配置
	tunnelPortStart, _ := cs.GetConfigInt("tunnel.port_range_start", 10000)
	tunnelPortEnd, _ := cs.GetConfigInt("tunnel.port_range_end", 65535)

	appConfig.Tunnel = models.TunnelConfig{
		PortRangeStart: tunnelPortStart,
		PortRangeEnd:   tunnelPortEnd,
	}

	// 域名路由配置
	domainRouterEnabled, _ := cs.GetConfigBool("domain_router.enabled", false)
	domainRouterPort, _ := cs.GetConfigInt("domain_router.port", 80)

	appConfig.DomainRouter = models.DomainRouterConfig{
		Enabled: domainRouterEnabled,
		Port:    domainRouterPort,
	}

	// 腾讯云配置
	tencentSecretID, _ := cs.GetConfig("tencent.secret_id")
	tencentSecretKey, _ := cs.GetConfig("tencent.secret_key")

	appConfig.Tencent = models.TencentConfig{
		SecretID:  tencentSecretID,
		SecretKey: tencentSecretKey,
	}

	// JWT配置
	jwtSecret, _ := cs.GetConfig("jwt.secret")
	jwtExpireHours, _ := cs.GetConfigInt("jwt.expire_hours", 24)

	appConfig.JWT = models.JWTConfig{
		Secret:      jwtSecret,
		ExpireHours: jwtExpireHours,
	}

	// 客户端配置
	clientBaseURL, _ := cs.GetConfig("client.base_url")
	clientTCPTunnelHost, _ := cs.GetConfig("client.tcp_tunnel_host")
	clientTCPTunnelPort, _ := cs.GetConfigInt("client.tcp_tunnel_port", 9001)
	clientTimeoutSeconds, _ := cs.GetConfigInt("client.timeout_seconds", 10)
	clientMockDelayMs, _ := cs.GetConfigInt("client.mock_delay_ms", 500)
	clientDefaultDomain, _ := cs.GetConfig("client.default_domain")
	clientAutoReconnect, _ := cs.GetConfigBool("client.auto_reconnect", false)

	appConfig.Client = models.ClientConfig{
		BaseURL:        clientBaseURL,
		TCPTunnelHost:  clientTCPTunnelHost,
		TCPTunnelPort:  clientTCPTunnelPort,
		TimeoutSeconds: clientTimeoutSeconds,
		MockDelayMs:    clientMockDelayMs,
		DefaultDomain:  clientDefaultDomain,
		AutoReconnect:  clientAutoReconnect,
	}

	return appConfig, nil
}

// GetConfigBool 获取布尔类型配置
func (cs *ConfigService) GetConfigBool(key string, defaultValue bool) (bool, error) {
	value, err := cs.GetConfig(key)
	if err != nil {
		return defaultValue, err
	}
	if value == "" {
		return defaultValue, nil
	}

	switch strings.ToLower(value) {
	case "true", "1", "yes", "on", "enabled":
		return true, nil
	case "false", "0", "no", "off", "disabled":
		return false, nil
	default:
		return defaultValue, fmt.Errorf("无效的布尔值: %s", value)
	}
}

// GetConfigInt 获取整数类型配置
func (cs *ConfigService) GetConfigInt(key string, defaultValue int) (int, error) {
	value, err := cs.GetConfig(key)
	if err != nil {
		return defaultValue, err
	}
	if value == "" {
		return defaultValue, nil
	}

	intValue, err := strconv.Atoi(value)
	if err != nil {
		return defaultValue, fmt.Errorf("无效的整数值 [%s]: %s", key, value)
	}
	return intValue, nil
}

// InitializeDefaultConfigs 初始化默认配置
func (cs *ConfigService) InitializeDefaultConfigs() error {
	defaultConfigs := map[string]struct {
		value string
		desc  string
	}{
		"dns.enabled":             {"false", "是否启用DNS服务"},
		"dns.providers":           {"dnspod", "支持的DNS提供商"},
		"dns.default_provider":    {"dnspod", "默认DNS提供商"},
		"dns.domain":              {"", "主域名"},
		"dns.public_ip":           {"", "公网IP地址"},
		"tunnel.port_range_start": {"10000", "隧道端口范围开始"},
		"tunnel.port_range_end":   {"65535", "隧道端口范围结束"},
		"domain_router.enabled":   {"false", "是否启用域名路由"},
		"domain_router.port":      {"80", "域名路由监听端口"},
		"tencent.secret_id":       {"", "腾讯云SecretId"},
		"tencent.secret_key":      {"", "腾讯云SecretKey"},
		"jwt.secret":              {"your-secret-key", "JWT密钥"},
		"jwt.expire_hours":        {"24", "JWT过期时间(小时)"},
		"client.base_url":         {"http://localhost:8080", "客户端API基础URL"},
		"client.tcp_tunnel_host":  {"127.0.0.1", "TCP隧道主机地址"},
		"client.tcp_tunnel_port":  {"9001", "TCP隧道端口"},
		"client.timeout_seconds":  {"10", "客户端请求超时时间(秒)"},
		"client.mock_delay_ms":    {"500", "模拟延迟时间(毫秒)"},
		"client.default_domain":   {"tunnel.example.com", "默认隧道域名"},
		"client.auto_reconnect":   {"false", "是否启用自动重连"},
	}

	for key, cfg := range defaultConfigs {
		// 检查配置是否已存在
		var existingConfig models.Config
		err := config.DB.Where("config_key = ?", key).First(&existingConfig).Error
		if err != nil {
			// 配置不存在，创建默认配置
			newConfig := models.Config{
				ConfigKey:   key,
				ConfigValue: cfg.value,
				Desc:        cfg.desc,
			}
			if err := config.DB.Create(&newConfig).Error; err != nil {
				log.Printf("⚠️  创建默认配置失败 [%s]: %v", key, err)
			} else {
				log.Printf("✅ 创建默认配置: %s = %s", key, cfg.value)
			}
		}
	}

	return nil
}

// ValidateConfig 验证配置的有效性
func (cs *ConfigService) ValidateConfig() error {
	appConfig, err := cs.GetAppConfig()
	if err != nil {
		return fmt.Errorf("获取应用配置失败: %v", err)
	}

	// 验证DNS配置
	if appConfig.DNS.Enabled {
		if appConfig.DNS.Domain == "" {
			return fmt.Errorf("DNS已启用但未配置域名")
		}
		if appConfig.DNS.PublicIP == "" {
			return fmt.Errorf("DNS已启用但未配置公网IP")
		}
		if appConfig.Tencent.SecretID == "" || appConfig.Tencent.SecretKey == "" {
			return fmt.Errorf("DNS已启用但未配置腾讯云密钥")
		}
	}

	// 验证端口范围
	if appConfig.Tunnel.PortRangeStart <= 0 || appConfig.Tunnel.PortRangeEnd <= 0 {
		return fmt.Errorf("隧道端口范围配置无效")
	}
	if appConfig.Tunnel.PortRangeStart >= appConfig.Tunnel.PortRangeEnd {
		return fmt.Errorf("隧道端口范围开始值必须小于结束值")
	}

	// 验证域名路由配置
	if appConfig.DomainRouter.Enabled {
		if appConfig.DomainRouter.Port <= 0 || appConfig.DomainRouter.Port > 65535 {
			return fmt.Errorf("域名路由端口配置无效")
		}
	}

	return nil
}

// GetConfigsAsJSON 获取所有配置的JSON格式
func (cs *ConfigService) GetConfigsAsJSON() (string, error) {
	appConfig, err := cs.GetAppConfig()
	if err != nil {
		return "", err
	}

	jsonData, err := json.MarshalIndent(appConfig, "", "  ")
	if err != nil {
		return "", fmt.Errorf("序列化配置失败: %v", err)
	}

	return string(jsonData), nil
}

// PrintAllConfigs 打印所有关键配置参数
func (cs *ConfigService) PrintAllConfigs() {
	log.Printf("📋 ======== 系统配置参数 ========")

	// 定义要打印的配置项
	configKeys := []string{
		"dns.enabled",
		"dns.providers",
		"dns.default_provider",
		"dns.domain",
		"dns.public_ip",
		"tunnel.port_range_start",
		"tunnel.port_range_end",
		"domain_router.enabled",
		"domain_router.port",
		"tencent.secret_id",
		"tencent.secret_key",
		"jwt.secret",
		"jwt.expire_hours",
		"client.base_url",
		"client.tcp_tunnel_host",
		"client.tcp_tunnel_port",
		"client.timeout_seconds",
		"client.mock_delay_ms",
		"client.default_domain",
		"client.auto_reconnect",
	}

	for _, key := range configKeys {
		value, err := cs.GetConfig(key)
		if err != nil {
			log.Printf("   %-25s = <未设置> (错误: %v)", key, err)
		} else {
			// 对敏感信息进行脱敏处理
			displayValue := value
			if strings.Contains(key, "secret") || strings.Contains(key, "key") {
				if len(value) > 8 {
					displayValue = value[:4] + "****" + value[len(value)-4:]
				} else if len(value) > 0 {
					displayValue = "****"
				}
			}
			log.Printf("   %-25s = %s", key, displayValue)
		}
	}
	log.Printf("📋 ================================")
}
